<template>
  <div class="visual-tree-wrap">
    <div class="visual-search-wrap">
      <div class="visual-search-content">
        <px-input v-model="filterText" placeholder="请输入关键字搜索" />
        <px-button link type="primary" @click="resetCheck"> 清除选中 </px-button>
      </div>
      <div class="visual-search-content">
        <px-radio-group v-model="treeCurClass" size="small" @change="treeClassChange">
          <px-radio-button label="全部" />
          <px-radio-button label="机械科" />
          <px-radio-button label="电科" />
          <px-radio-button label="水科" />
          <px-radio-button label="气化科" />
        </px-radio-group>
      </div>

      <px-scrollbar class="equip-scroller">
        <px-tree
          ref="treeRef"
          highlight-current
          :expand-on-click-node="false"
          node-key="code"
          :data="leftTreeData"
          :props="defaultProps"
          :filter-node-method="filterNode"
          :default-expanded-keys="expendKeys"
          @node-click="nodeClick"
        >
          <template #default="{ node }">
            <div class="w-[270px] flex">
              <div class="w-[140px]">
                <ReTextTooltip :content="node.label" />
              </div>
              <div class="flex flex-grow-0 flex-shrink-0">
                <px-button type="primary" link :icon="EditPen" @click="itemEdit(node)" />
                <px-button type="danger" link :icon="Remove" @click="itemDel(node)" />
                <px-button type="primary" link :icon="CirclePlus" @click="itemAdd(node)" />
              </div>
            </div>
          </template>
        </px-tree>
      </px-scrollbar>
    </div>
    <div class="visual-table-wrap">
      <px-tabs v-model="activeKey" class="dropdown-tabs" :style="{ width: '100%' }" @tab-click="tabClick">
        <px-tab-pane label="设备列表" name="eqpList">
          <EqpListPane
            :tree-select="treeSelect"
            active-name="eqpList"
            :activeKey="activeKey"
            :positionCode="positionCode"
            :imgUploadCut="imgUploadCut"
            @handleUploadPic="handleUploadPic"
          />
        </px-tab-pane>
        <px-tab-pane label="设备组列表" name="eqpGroupList">
          <GroupAddEqpPane
            :tree-select="treeSelect"
            :imgUploadCut="imgUploadCut"
            :positionCode="positionCode"
            :activeKey="activeKey"
            active-name="eqpGroupList"
            @handleUploadPic="handleUploadPic"
          />
        </px-tab-pane>
        <px-tab-pane label="消防设备列表" name="hseList">
          <EqpListPane
            :tree-select="treeSelect"
            active-name="hseList"
            :activeKey="activeKey"
            :positionCode="positionCode"
            :imgUploadCut="imgUploadCut"
            eqpType="ERC"
            @handleUploadPic="handleUploadPic"
          />
        </px-tab-pane>
        <px-tab-pane label="消防设备组列表" name="hseGroupList">
          <GroupAddEqpPane
            :tree-select="treeSelect"
            :imgUploadCut="imgUploadCut"
            :positionCode="positionCode"
            active-name="hseGroupList"
            eqpType="ERC"
            :activeKey="activeKey"
            @handleUploadPic="handleUploadPic"
          />
        </px-tab-pane>
        <px-tab-pane label="摄像头列表" name="cameraList">
          <CameraListPane
            :tree-select="treeSelect"
            active-name="cameraList"
            :activeKey="activeKey"
            :positionCode="positionCode"
            :imgUploadCut="imgUploadCut"
            @handleUploadPic="handleUploadPic"
          />
        </px-tab-pane>
      </px-tabs>
    </div>
    <px-drawer
      v-model="open"
      :close-on-click-modal="false"
      :title="isTreeEditor ? '修改位置' : '新增位置'"
      width="600px"
      destroy-on-close
      append-to-body
      @close="cancel"
    >
      <px-form ref="positionRef" :model="formValue" :rules="rules" label-width="120px">
        <px-form-item label="父级位置" prop="parentCode">
          <px-tree-select
            v-model="formValue.parentCode"
            style="width: 100%"
            :data="treeData"
            :props="defaultProps"
            node-key="code"
            check-strictly
            :render-after-expand="false"
            placeholder="请选择所属父级"
            filterable
            @node-click="handleNodeClick"
          />
        </px-form-item>
        <px-form-item label="位置名称" prop="name">
          <px-input v-model="formValue.name" maxlength="50" placeholder="请输入位置名称" />
        </px-form-item>
        <px-form-item label="位置类型" prop="type">
          <px-select v-model="formValue.type" style="width: 100%">
            <px-option v-for="item in typeList" :key="item.value" :label="item.name" :value="item.value" />
          </px-select>
        </px-form-item>
        <px-form-item label="科室" prop="className">
          <px-select v-model="formValue.className" style="width: 100%" clearable>
            <px-option v-for="item in classNameList" :key="item.id" :label="item.name" :value="item.value" />
          </px-select>
        </px-form-item>
        <px-form-item label="是否可点击">
          <px-switch v-model="formValue.isClick" :active-value="1" :inactive-value="0" size="small" />
        </px-form-item>
        <px-form-item label="排序" prop="orderSeq">
          <px-input-number v-model="formValue.orderSeq" :min="0" />
        </px-form-item>
      </px-form>
      <template #footer>
        <div class="dialog-footer">
          <px-button type="primary" @click="submitForm">确 定</px-button>
          <px-button @click="cancel">取 消</px-button>
        </div>
      </template>
    </px-drawer>
    <px-dialog v-model="uploadShow" title="请选择上传图片" width="30%" align-center @close="uploadPicClose">
      <PhotoUpload
        v-if="uploadShow"
        photoType="add"
        :photoData="{ moduleName: 'twins_visualization' }"
        :photoList="pictureLists"
        :eqpId="picEqpId"
        :updateType="updateType"
        :eqpType="eqpType"
        @changePhotoList="changePhotoList"
      />
      <px-checkbox v-model="updateType" true-label="1" false-label="0" label="同类型更新" size="large" />
    </px-dialog>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "ALL_VISUAL_TREE_CONFIG"
});
import { queryVisualTree, visualTreeSave, delTreeItemById } from "@/api/visual/visualConfig";
import { getEquipNameSelect, getEquipTypeSelect } from "@/api/equip/archive";
import { getEmployeeIdAndName } from "@/utils/pengxi";

import { getCurrentInstance, onMounted, reactive, toRaw, toRefs, watch } from "vue";
import ReTextTooltip from "../components/ReTextTooltip";
import { CirclePlus, Remove, EditPen } from "@px-ui/icons-vue";

import EqpListPane from "./eqpListPane.vue";
import GroupAddEqpPane from "./groupAddEqpPane.vue";
import CameraListPane from "./cameraListPane.vue";

import { PxMessage, PxMessageBox } from "px-ui";
import { queryDictData } from "@/api/common";
const { proxy }: any = getCurrentInstance();
import { downloadPic } from "@visual/api/api";

import PhotoUpload from "../components/PhotoUpload2.vue";

const classMap = {
  机械科: "MACHINE",
  电科: "ELECTRICTITY",
  水科: "WATER",
  气化科: "GAS"
};
const state = reactive<any>({
  filterText: "",
  treeRef: null,
  treeData: [],
  leftTreeData: [],
  treeSelect: null,
  positionCode: null,
  categoryIdList: [],
  typeIdList: [],
  equipTitle: "全部",
  queryParams: {
    eqpId: ""
  },
  tableData: [],
  total: 0,
  visible: false,
  isTreeEditor: false,
  formValue: {
    orderSeq: 0,
    isVisualization: 1,
    isClick: 1
  },
  rules: {
    parentCode: [{ required: true, message: "父级位置不能为空", trigger: "blur" }],
    name: [{ required: true, message: "位置名称不能为空", trigger: "blur" }],
    type: [{ required: true, message: "位置类型不能为空", trigger: "blur" }]
  },
  principalList: [],
  typeList: [],
  classNameList: [],
  isChild: false,
  open: false,
  facCode: localStorage.getItem("facCode"), // 厂区编码
  uploadShow: false,
  pictureLists: [],
  picEqpId: "",
  eqpImgList: {},
  eqpTextOpen: false,
  eqpText: "",
  selectedTable: [],
  expendKeys: [localStorage.getItem("facCode")],
  activeKey: "eqpList",
  groupTableData: [],
  groupOpen: false,
  groupName: "",
  groupNameRow: false,
  groupEqpTableData: [],
  currentGroup: null,
  groupAddEqpOpen: false,
  updateType: "1",
  eqpType: "IFP",
  imgUploadCut: 0,
  treeCurClass: "全部"
});

const {
  filterText,
  treeRef,
  treeData,
  leftTreeData,
  treeSelect,
  positionCode,
  categoryIdList,
  typeIdList,
  equipTitle,
  queryParams,
  tableData,
  total,
  visible,
  isTreeEditor,
  formValue,
  rules,
  principalList,
  isChild,
  facCode,
  typeList,
  open,
  classNameList,
  uploadShow,
  pictureLists,
  picEqpId,
  eqpImgList,
  imgUploadCut,
  selectedTable,
  expendKeys,
  activeKey,
  eqpType,
  updateType,
  treeCurClass
} = toRefs(state);

const defaultProps = {
  children: "children",
  value: "code",
  label: "name",
  key: "code"
};

// 监视过滤树的值
watch(filterText, val => {
  treeRef.value!.filter(val);
});

// 进入页面时触发
onMounted(async () => {
  treeSelect.value = null;
  positionCode.value = null;
  await queryTree();
  await queryCategoryIdSelect();
  await queryTypeIdSelect();
  await handleGetDictData();
  principalList.value = await getEmployeeIdAndName();
  // queryTable();
});

// 设备总称下拉框
const queryCategoryIdSelect = async () => {
  categoryIdList.value = [{ name: "全部", id: "" }];
  const data = await getEquipNameSelect({});
  categoryIdList.value = categoryIdList.value.concat(data).map(item => ({ label: item.name, value: item.id }));
};

// 设备类型下拉框
const queryTypeIdSelect = async () => {
  typeIdList.value = [{ name: "全部", id: "" }];
  const data = await getEquipTypeSelect({});
  typeIdList.value = typeIdList.value.concat(data).map(item => ({ label: item.name, value: item.id }));
};

// 查询左侧树
const queryTree = async (needEqp = false) => {
  const data: any = await queryVisualTree({ facCode: facCode.value, needEqp });
  const filter = data.filter(item => item.isVisualization !== 0);
  treeData.value = filter;
  leftTreeData.value = filter;
};
// 过滤树数据
const filterNode = (value: string, data) => {
  if (!value) return true;
  return data.name.includes(value);
};
// 左侧树添加清除选中按钮
const resetCheck = () => {
  treeSelect.value = null;
  formValue.value.parentCode = "";
  filterText.value = "";
  equipTitle.value = "全部";
  const selectedNodes = document.querySelectorAll(".is-current");
  selectedNodes.forEach(element => {
    element.classList.remove("is-current");
  });
  queryParams.value = {
    eqpId: ""
  };
};
// 点击左侧树节点，获取categoryId，查询设备列表
const nodeClick = (elemData, nodeData) => {
  treeSelect.value = elemData;
  positionCode.value = treeSelect.value.code;
  facCode.value = elemData.facCode;
};
// 查询设备列表

const handleUploadPic = async (row, type) => {
  picEqpId.value = row.eqpId;
  eqpType.value = type;
  uploadShow.value = true;
};
const cancel = () => {
  open.value = false;
  proxy.resetForm("positionRef");
  facCode.value = "";
  formValue.value = {
    orderSeq: 0,
    isVisualization: 1,
    isClick: 1
  };
};
const submitForm = () => {
  proxy.$refs["positionRef"].validate(async valid => {
    if (valid) {
      if (formValue.value.id) {
        await visualTreeSave({ facCode: facCode.value, ...formValue.value, code: treeSelect.value.code });
        PxMessage.success("修改成功");
      } else {
        await visualTreeSave({ facCode: facCode.value, ...formValue.value });
        PxMessage.success("新增成功");
      }
      await queryTree();
      if (treeSelect.value) {
        const { code } = treeSelect.value;
        if (code) expendKeys.value = [code];
      }
      cancel();
    }
  });
};
const handleNodeClick = val => {
  facCode.value = val.facCode;
};
const handleGetDictData = async () => {
  const data = await queryDictData({ typeCode: "fac_position_type" });
  typeList.value = data.filter(item => item.value !== "FAC"); // 厂区只能在数据字典添加
  classNameList.value = await queryDictData({ typeCode: "className" });
};

const itemAdd = node => {
  formValue.value.parentCode = node.data.code;
  open.value = true;
};
const itemDel = node => {
  const { id, code: positionCode, parentCode } = node.data;
  PxMessageBox.confirm('是否确认删除名称为"' + node.data.name + '"的数据项？', "温馨提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    draggable: true
  })
    .then(async () => {
      const res = await delTreeItemById({ id, positionCode });
      PxMessage({
        message: "删除成功",
        type: "success"
      });
      await queryTree();
      if (parentCode) expendKeys.value = [parentCode];
    })
    .catch(() => {});
};
const itemEdit = node => {
  const { id, name, type, className, orderSeq, parentCode, isClick } = node.data;
  formValue.value = { id, name, type, className, orderSeq, parentCode, isVisualization: 1, isClick };

  facCode.value = node.facCode;
  open.value = true;
};
const changePhotoList = (val, flag) => {
  pictureLists.value = val;
  if (flag === "success") {
    uploadPicClose();
    imgUploadCut.value += 1;
    eqpImgList.value = {};
  }
};
const uploadPicClose = () => {
  uploadShow.value = false;
  pictureLists.value = [];
  picEqpId.value = "";
  updateType.value = "1";
};
const getImagByName = async name => {
  if (!name) return;
  if (eqpImgList.value[name]) {
    return eqpImgList.value[name];
  }
  let res = await downloadPic({ originalName: name, moduleName: "twins_visualization" });
  if (res && res[0]) {
    const { fileUrl } = res[0];
    eqpImgList.value[name] = fileUrl;
    return fileUrl;
  }
  return "";
};

const tabClick = async (tab, a) => {
  if (tab.paneName == "cameraList") {
    await queryTree(true);
    resetCheck();
  } else if (activeKey.value == "cameraList" && activeKey.value != tab.paneName) {
    await queryTree();
    resetCheck();
  }
  activeKey.value = tab.paneName;
};
const treeClassChange = item => {
  if (item === "全部") {
    leftTreeData.value = toRaw(treeData.value);
  } else {
    leftTreeData.value = filterTree(toRaw(treeData.value), "className", classMap[item]);
  }
};
/**
 * 过滤一棵/多棵树，保留完整层级路径
 * @param {Array<Object>} nodes  原始树形数组
 * @param {String} key           要匹配的字段名
 * @param {*} value              要匹配的字段值
 * @returns {Array<Object>}      过滤后的新树
 */
function filterTree(nodes, key, value) {
  return nodes.reduce((acc, node) => {
    const hit = node[key] === value; // 当前节点是否命中
    const children = node.children || []; // 防御空 children
    // 递归过滤子节点
    const filteredChildren = children.length ? filterTree(children, key, value) : [];

    // 若自身命中或任一后代命中 → 保留当前节点
    if (hit || filteredChildren.length) {
      acc.push({
        ...node,
        children: filteredChildren // 用过滤后的 children
      });
    }
    return acc;
  }, []);
}
</script>

<style lang="scss" scoped>
.visual-tree-wrap {
  position: relative;
  box-sizing: border-box;
  display: flex;
  width: 100%;
  height: calc(100vh - 177px);
  padding: 24px 24px 0;
  background-color: #fff;
  border-radius: 8px;

  .equip-scroller {
    height: calc(100vh - 280px);
  }

  .visual-search-wrap {
    width: 300px;
    height: calc(100vh - 222px);
    padding: 12px;
    margin-right: 16px;
    border: 1px solid #dfdfdf;

    .visual-search-content {
      display: flex;
      align-items: center;
      margin-bottom: 12px;
    }

    :deep(.px-tree) {
      display: inline-block;
      min-width: 100%;
    }

    :deep(.px-button) {
      margin-left: 0 !important;
    }

    .visual-scroller {
      height: calc(100vh - 280px);
    }
  }

  .visual-table-wrap {
    width: calc(100% - 316px);

    .visual-title {
      margin-bottom: 10px;
    }

    .visual-table {
      --px-table-border-color: #dfdfdf;

      :deep(.px-table__header) {
        thead {
          tr {
            background-color: #e7eefb !important;

            th {
              font-size: 13px;
              font-weight: bold;
              color: #000;
              background-color: #e7eefb !important;
            }
          }
        }
      }
    }

    .visual-pagination {
      position: absolute;
      right: 8px;
      bottom: 0;
    }
  }
}
</style>
